package com.xjscrm.server.service.grouppull.impl;

import com.xjscrm.common.annotation.MerId;
import com.xjscrm.common.entity.WwCustomer;
import com.xjscrm.common.enums.RedisCacheKeyEnum;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.vo.grouppull.*;
import com.xjscrm.server.biz.mq.producer.SendMsgProducer;
import com.xjscrm.server.mapper.*;
import com.xjscrm.server.service.grouppull.GroupPullDataService;
import com.xjscrm.server.vo.device.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 群邀请处理数据
 *
 * @author makejava
 * @since 2024-03-01 17:01:12
 */
@Slf4j
@Service
public class GroupPushDataServiceImpl implements GroupPullDataService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SendMsgProducer sendMsgProducer;
    @Autowired
    private WwDeviceMapper wwDeviceMapper;
    @Autowired
    private WwGroupMapper wwGroupMapper;
    @Autowired
    private WwGroupMemberMapper wwGroupMemberMapper;
    @Autowired
    private WwGroupTagsRelationMapper wwGroupTagsRelationMapper;
    @Autowired
    private WwCustomerTagsMapper wwCustomerTagsMapper;
    @Autowired
    private WwCustomerMapper wwCustomerMapper;
    @Autowired
    private GroupPullConfigDeviceMapper groupPullConfigDeviceMapper;
    @Autowired
    private GroupPullConfigMapper groupPullConfigMapper;
    @Autowired
    private GroupPullMarketingMapper groupPullMarketingMapper;

    /**
     * 处理邀请群数据
     *
     * @param groupPullDataList
     * @param wwCustomer
     * @param device
     * @author jitwxs
     * @date 2024/4/7 20:41
     */
    public List<GroupPullMsgData> handGroupPullData(@MerId Long merId, List<GroupPullData> groupPullDataList, WwCustomer wwCustomer, Device device) {

        if (groupPullDataList == null || groupPullDataList.size() == 0) {
            return null;
        }

        //封装拉群发送消息
        List<GroupPullMsgData> msgDataList_all = new ArrayList<>();
        for (GroupPullData groupPullData : groupPullDataList) {
            if (groupPullData.getMsgType().intValue() != 100) { //不是拉群指令，则直接封装消息
                GroupPullMsgData groupPullMsgData = new GroupPullMsgData();
                BeanUtils.copyProperties(groupPullData, groupPullMsgData);
                msgDataList_all.add(groupPullMsgData);
            } else if (groupPullData.getMsgType().intValue() == 100) { //拉群信息，则需要封装拉群指令
                //如果会员等于空，则没有拉群数据
                if (wwCustomer != null) {
                    //未进群，再次邀请拉群数据格式
                    List<AgainData> notJoinInvitationAgain = null;
                    //已进群，再次营销数据格式
                    List<AgainData> joinedMarketingAgain = null;

                    //未进群，再次邀请开关（0-关闭，1-开启)
                    Integer notJoinInvitationAgainSwith = Tools.getInteger(groupPullData.getNotJoinInvitationAgainSwith());
                    if (notJoinInvitationAgainSwith.intValue() == 1) { //开启未进群再次拉群功能
                        notJoinInvitationAgain = groupPullData.getNotJoinInvitationAgain();
                    }

                    //已进群，再次营销开关（0-关闭，1-开启)
                    Integer joinedMarketingAgainSwith = Tools.getInteger(groupPullData.getJoinedMarketingAgainSwith());
                    if (joinedMarketingAgainSwith.intValue() == 1) { //开启已进群再次营销功能
                        joinedMarketingAgain = groupPullData.getJoinedMarketingAgain();
                    }

                    //临时封装需要进的群信息
                    List<GroupPullMsgData> groupPullMsgDataList_group = new ArrayList<>();
                    GroupRule groupRule = getGroupRuleInfoListByDevice(groupPullData, device);
                    if (groupRule == null) {
                        continue;
                    }
                    //查找该机器人所在的群详细信息
                    List<GroupRuleInfo> groupRuleInfoList = groupRule.getGroupRuleInfos();
                    if (groupRuleInfoList == null || groupRuleInfoList.size() == 0) {
                        continue;
                    }
                    Integer pullType = Tools.getInteger(groupPullData.getPullType());
                    if (pullType.intValue() == 1) { //拉近已有群
                        //拉群模式（0-拉进以上全部群；1-随机一个群；2-按照顺序成员达上限后自动切换到下一个群）
                        Integer pullModel = Tools.getInteger(groupPullData.getPullModel());
                        //全部拉群
                        if (pullModel.intValue() == 0) {//全部拉群
                            //查找符合性别配置和群成员人数的群
                            List<GroupRuleInfo> groupRuleInfoList_gender = verifyGendersGroupPullByExistGroup(groupPullData, groupRuleInfoList, wwCustomer, device);
                            if (groupRuleInfoList_gender != null && groupRuleInfoList_gender.size() > 0) {
                                for (int i = 0; i < groupRuleInfoList_gender.size(); i++) {
                                    GroupRuleInfo groupRuleInfo = groupRuleInfoList_gender.get(i);
                                    if (groupRuleInfo == null) {
                                        continue;
                                    }
                                    GroupPullMsgData groupPullMsgData = new GroupPullMsgData();
                                    groupPullMsgData.setMsgType(101); //拉进已有群
                                    if (i == 0) { //第一个群的延迟时间，从规则中回去
                                        groupPullMsgData.setGap(groupPullData.getGap());
                                        groupPullMsgData.setUnit(groupPullData.getUnit());
                                    } else {//后面群的延迟时间，从群间隔时间获取
                                        groupPullMsgData.setGap(Tools.getInteger(groupPullData.getIntervalTime()));
                                        groupPullMsgData.setUnit(1);
                                    }

                                    groupPullMsgData.setGroupId(groupRuleInfo.getGroupWxid());
                                    groupPullMsgData.setWxIds(wwCustomer.getWxid());
                                    groupPullMsgData.setNotJoinInvitationAgain(notJoinInvitationAgain);
                                    groupPullMsgData.setJoinedMarketingAgain(joinedMarketingAgain);
                                    groupPullMsgDataList_group.add(groupPullMsgData);
                                }
                            }
                        } else if (pullModel.intValue() == 1) { //随机一个群
                            //查找出符合性别验证的群列表
                            //查找符合性别配置的群
                            List<GroupRuleInfo> groupRuleInfoList_gender = verifyGendersGroupPullByExistGroup(groupPullData, groupRuleInfoList, wwCustomer, device);
                            if (groupRuleInfoList_gender != null && groupRuleInfoList_gender.size() > 0) {
                                int rateMin = 0;
                                int rateMax = groupRuleInfoList_gender.size() - 1;
                                //获取最小和最大时间的随机数（分数）
                                int rateRandom = (int) (Math.random() * (rateMax - rateMin + 1) + rateMin);
                                GroupRuleInfo groupRuleInfo_random = groupRuleInfoList_gender.get(rateRandom);
                                if (groupRuleInfo_random == null) {
                                    continue;
                                }
                                GroupPullMsgData groupPullMsgData = new GroupPullMsgData();
                                groupPullMsgData.setMsgType(101); //拉进已有群
                                groupPullMsgData.setGap(groupPullData.getGap());
                                groupPullMsgData.setUnit(groupPullData.getUnit());
                                groupPullMsgData.setGroupId(groupRuleInfo_random.getGroupWxid());
                                groupPullMsgData.setWxIds(wwCustomer.getWxid());
                                groupPullMsgData.setNotJoinInvitationAgain(notJoinInvitationAgain);
                                groupPullMsgData.setJoinedMarketingAgain(joinedMarketingAgain);
                                groupPullMsgDataList_group.add(groupPullMsgData);
                            }
                        } else {//按照顺序成员达上限后自动切换到下一个群
                            GroupRuleInfo groupRuleInfo_orderIndex = verifyOrderIndexGroupPullByExistGroup(groupPullData, groupRuleInfoList, wwCustomer, device);
                            if (groupRuleInfo_orderIndex != null) {
                                GroupPullMsgData groupPullMsgData = new GroupPullMsgData();
                                groupPullMsgData.setMsgType(101); //拉进已有群
                                groupPullMsgData.setGap(groupPullData.getGap());
                                groupPullMsgData.setUnit(groupPullData.getUnit());
                                groupPullMsgData.setGroupId(groupRuleInfo_orderIndex.getGroupWxid());
                                groupPullMsgData.setWxIds(wwCustomer.getWxid());
                                groupPullMsgData.setNotJoinInvitationAgain(notJoinInvitationAgain);
                                groupPullMsgData.setJoinedMarketingAgain(joinedMarketingAgain);
                                groupPullMsgDataList_group.add(groupPullMsgData);
                            }
                        }

                        //判断是否创建新群,未找到合适的群，则创建新群
                        if (groupPullMsgDataList_group == null || groupPullMsgDataList_group.size() == 0) {
                            Integer createGroupSwitch = Tools.getInteger(groupPullData.getCreateGroupSwitch());
                            if (createGroupSwitch.intValue() == 1) { //开启创建新群

                                //创建新群群名
                                String createGroupName = Tools.getStr(groupPullData.getCreateGroupName());
                                //创建新群群名随机下标
                                Integer createGroupNameStartNo = Tools.getInteger(groupPullData.getCreateGroupNameStartNo());

                                //从缓存中获取当前创建新群群名开始下标
                                String group_pull_group_name_start_no_key = String.format(RedisCacheKeyEnum.GROUP_PULL_GROUP_NAME_START_NO.getKey(), groupPullData.getGroupPullKey(), device.getDeviceUniqueId());
                                Integer group_pull_group_name_start_no = (Integer) redisTemplate.opsForValue().get(group_pull_group_name_start_no_key);
                                //判断缓存中的下标和配置页面上保存的下标值大小，优先大的下标
                                if (group_pull_group_name_start_no != null && group_pull_group_name_start_no.intValue() >= createGroupNameStartNo.intValue()) {
                                    //更新缓存
                                    redisTemplate.opsForValue().increment(group_pull_group_name_start_no_key);
                                    createGroupNameStartNo = Tools.getInteger(group_pull_group_name_start_no) + 1;
                                } else {
                                    redisTemplate.opsForValue().set(group_pull_group_name_start_no_key, createGroupNameStartNo);
                                }

                                //预设群成员
                                List<String> memberWxidList = new ArrayList<>();
                                memberWxidList.add(wwCustomer.getWxid());
                                List<Long> customerIdList = groupRule.getCustomerIds();
                                if (customerIdList == null || customerIdList.size() == 0) {
                                    continue;
                                }

                                for (Long customerId : customerIdList) {
                                    WwCustomer wwCustomer_member = wwCustomerMapper.queryById(customerId);
                                    if (wwCustomer_member != null) {
                                        String wxid_member = wwCustomer_member.getWxid();
                                        memberWxidList.add(wxid_member);
                                    }
                                }

                                GroupPullMsgData groupPullMsgData = new GroupPullMsgData();
                                groupPullMsgData.setMsgType(102); //创建新群
                                groupPullMsgData.setGap(groupPullData.getGap());
                                groupPullMsgData.setUnit(groupPullData.getUnit());
                                groupPullMsgData.setGroupName(createGroupName + createGroupNameStartNo);
                                groupPullMsgData.setWxIds(StringUtils.join(memberWxidList, ";"));
                                groupPullMsgDataList_group.add(groupPullMsgData);
                            }
                        }
                    } else { //按条件选择群,目前版本暂时不支持
                        continue;
                    }

                    //将消息添加到拉群消息列表中
                    msgDataList_all.addAll(groupPullMsgDataList_group);
                }
            }
        }
        return msgDataList_all;
    }

    //查找该机器人配置的群信息
    public GroupRule getGroupRuleInfoListByDevice(GroupPullData groupPullData, Device device) {

        List<GroupRule> groupRules = groupPullData.getGroupRules();
        if (groupRules == null || groupRules.size() == 0) {
            return null;
        }

        //查找该机器人所在的群信息
        GroupRule groupRule = groupRules.stream().filter(item -> Objects.equals(device.getDeviceId(), item.getDeviceId())).findFirst().orElse(null);
        if (groupRule == null) {
            return null;
        }

        return groupRule;
    }

    //从机器人配置的群列表中选择符合性别的群
    public List<GroupRuleInfo> verifyGendersGroupPullByExistGroup(GroupPullData groupPullData, List<GroupRuleInfo> groupRuleInfoList, WwCustomer wwCustomer, Device device) {
        List<GroupRuleInfo> groupRuleInfoList_gender = new ArrayList<>();

        //群配置成员数上限
        Integer groupUserCount = Tools.getInteger(groupPullData.getGroupUserCount());

        //查找该机器人所在的群详细信息
        for (GroupRuleInfo groupRuleInfo : groupRuleInfoList) {
            //获取此群的成员数
            String groupMermberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), groupRuleInfo.getGroupWxid());
            Integer groupMermberCount = (Integer) redisTemplate.opsForValue().get(groupMermberCountKey);
            List<Integer> genders = groupRuleInfo.getGenders();
            if (genders == null || genders.size() == 0) { //性别不限
                //群人数是否小于配置的成员数
                if (Tools.getInteger(groupMermberCount).intValue() < groupUserCount.intValue()) {
                    groupRuleInfoList_gender.add(groupRuleInfo);
                }
            } else {
                if (genders.contains(Tools.getInteger(wwCustomer.getGender()))) {
                    //群人数是否小于配置的成员数
                    if (Tools.getInteger(groupMermberCount).intValue() < groupUserCount.intValue()) {
                        groupRuleInfoList_gender.add(groupRuleInfo);
                    }
                }
            }
        }
        return groupRuleInfoList_gender;
    }

    //从机器人配置的群列表中选择符当前进粉的群
    public GroupRuleInfo verifyOrderIndexGroupPullByExistGroup(GroupPullData groupPullData, List<GroupRuleInfo> groupRuleInfoList, WwCustomer wwCustomer, Device device) {
        GroupRuleInfo groupRuleInfo_orderIndex = null;
        //获取当前进粉群下标
        String group_pull_order_index_key = String.format(RedisCacheKeyEnum.GROUP_PULL_ORDER_INDEX.getKey(), groupPullData.getGroupPullKey(), device.getDeviceUniqueId());
        Integer group_pull_order_index = (Integer) redisTemplate.opsForValue().get(group_pull_order_index_key);
        group_pull_order_index = Tools.getInteger(group_pull_order_index);//如果为空，则默认为第一个，下标为0
        //群配置成员数上限
        Integer groupUserCount = Tools.getInteger(groupPullData.getGroupUserCount());
        for (int i = group_pull_order_index; i < groupRuleInfoList.size(); i++) {
            GroupRuleInfo groupRuleInfo = groupRuleInfoList.get(i);
            //获取此群的成员数
            String groupMermberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), groupRuleInfo.getGroupWxid());
            Integer groupMermberCount = (Integer) redisTemplate.opsForValue().get(groupMermberCountKey);
            //群人数是否小于配置的成员数
            if (Tools.getInteger(groupMermberCount).intValue() < groupUserCount.intValue()) {
                groupRuleInfo_orderIndex = groupRuleInfo;
                redisTemplate.opsForValue().set(group_pull_order_index_key, i);
                break;
            }
        }

        //判断是否找到，如果未找到，则判断是否需要从头开始替补循环
        if (groupRuleInfo_orderIndex == null) {
            Integer autoFill = Tools.getInteger(groupPullData.getAutoFill());
            if (autoFill.intValue() == 1) { //开始循环替补，再次从头开始循环
                for (int i = 0; i < groupRuleInfoList.size(); i++) {
                    GroupRuleInfo groupRuleInfo = groupRuleInfoList.get(i);
                    //获取此群的成员数
                    String groupMermberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), groupRuleInfo.getGroupWxid());
                    Integer groupMermberCount = (Integer) redisTemplate.opsForValue().get(groupMermberCountKey);
                    //群人数是否小于配置的成员数
                    if (Tools.getInteger(groupMermberCount).intValue() < groupUserCount.intValue()) {
                        groupRuleInfo_orderIndex = groupRuleInfo;
                        redisTemplate.opsForValue().set(group_pull_order_index_key, i);
                        break;
                    }
                }
            }
        }

        return groupRuleInfo_orderIndex;
    }
}
